#ifndef __MARS_SCENEGRAPH_SCENENODE_H__
#define __MARS_SCENEGRAPH_SCENENODE_H__

#include "MarsObject.h"
#include "MarsSpatial.h"
#include "MarsRenderObject.h"

using namespace Graphics;

namespace GObject
{

class Camera;

} // end of namespace GObject


namespace SceneGraph
{

class TransformationData;

class SceneNode : public Core::Object
{
public:
									SceneNode( SceneNode* pParentNode = NULL );
									SceneNode( const std::string& strName, SceneNode* pParentNode = NULL );
	virtual							~SceneNode();

	const std::string&				GetName() const;

	void							AddChild( SceneNode* pSceneNode );

	void							RemoveChild( SceneNode* pChildSceneNode );
	void							RemoveChild( const std::string& strName );

	void							SetParent( SceneNode* pParentNode );

	void							SetPosition( const XMVECTOR& position );
	void							SetRotate( const XMVECTOR& rotate );
	void							SetScale( const XMVECTOR& scale );

	virtual void					Update( const XMMATRIX& matParentWorld );
	virtual void					Render( const GObject::Camera& camera, RenderObjectArray& arrRenderObjects );

protected:
	void							Initialize();
	void							Shutdown();

	void							UpdateTransformation( const XMMATRIX& matParentWorld );
	void							UpdateBounding();

	Spatial*						m_pSpatial;
	TransformationData*				m_pTransform;
	SceneNode*						m_pParentNode;
	std::string						m_strName;

	typedef std::map< std::string, SceneNode* >	SceneNodeMap;
	typedef SceneNodeMap::iterator				SceneNodeMapItr;
	typedef SceneNodeMap::const_iterator		SceneNodeMapConstItr;

	SceneNodeMap					m_mapChildNodes;

private:
	static uint32					m_uiSceneNodeCount;
};

inline const std::string& SceneNode::GetName() const
{
	return m_strName;
}

inline void SceneNode::SetPosition( const XMVECTOR& position )
{
	MARS_ASSERT( m_pSpatial );
	m_pSpatial->SetPosition( position );
}

inline void SceneNode::SetRotate( const XMVECTOR& rotate )
{
	MARS_ASSERT( m_pSpatial );
	m_pSpatial->SetRotate( rotate );
}

inline void SceneNode::SetScale( const XMVECTOR& scale )
{
	MARS_ASSERT( m_pSpatial );
	m_pSpatial->SetScale( scale );
}

} // end of namespace SceneGraph


#endif // end of #ifndef __MARS_SCENEGRAPH_SCENENODE_H__